#include "os.h"
#include "msp_thread.h"

#ifndef WIN32
typedef struct {
	pthread_mutex_t	thr_mutex;
	pthread_cond_t	thr_cond;
	pthread_t		thr_id;
	int				pause_flag;
}thread_args, *p_thread_args;
#endif

msp_threadhandle msp_beginthread( ThreadProc proc, void* params )
{
#if defined(WIN32) || defined(WINCE)
	DWORD thrd_id;
	msp_threadhandle thrd_hd = CreateThread(NULL, 0, proc, params, 0, &thrd_id);
	return thrd_hd;
#else
	msp_threadhandle thrd_hd;
	pthread_attr_t attr;
	p_thread_args args = (p_thread_args)malloc(sizeof(thread_args));

	pthread_mutex_init(&(args->thr_mutex), NULL);
	pthread_cond_init(&(args->thr_cond), NULL);
	args->pause_flag = 0;
#ifndef _FLASH
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	thrd_hd = pthread_create(&(args->thr_id), &attr, proc, params);
	pthread_attr_destroy(&attr);
#endif
	if ( thrd_hd != 0 )
	{
		pthread_mutex_destroy(&(args->thr_mutex));
		pthread_cond_destroy(&(args->thr_cond));
		free(args);
		return NULL;
	}
	return (msp_threadhandle)args;
#endif
}

int msp_closehandle( msp_threadhandle thrd_hd )
{
#if defined(WIN32) || defined(WINCE)
	CloseHandle(thrd_hd);
#else
	p_thread_args args = (p_thread_args)thrd_hd;
	if ( args == 0 || args->thr_id == 0 )
		return 0;

	//pthread_join(thrd_hd, -1);
	pthread_mutex_destroy(&(args->thr_mutex));
	pthread_cond_destroy(&(args->thr_cond));
	free(args);
#endif

	return 0;
}

void msp_thread_suspend(msp_threadhandle thrd_hd)
{
#if defined(WIN32) || defined(WINCE)
	SuspendThread (thrd_hd);
#else
	p_thread_args args = (p_thread_args)thrd_hd;
	if ( args == 0 || args->thr_id == 0 )
		return;

	if ( args->pause_flag == 0 )
	{
		pthread_mutex_lock(&(args->thr_mutex));
		args->pause_flag = 1;
		pthread_mutex_unlock(&(args->thr_mutex));
	}
#endif
}

void msp_thread_resume(msp_threadhandle thrd_hd)
{
#if defined(WIN32) || defined(WINCE)
	ResumeThread (thrd_hd);
#else
	p_thread_args args = (p_thread_args)thrd_hd;
	if ( args == 0 || args->thr_id == 0 )
		return;

	if ( args->pause_flag == 1 )
	{
		pthread_mutex_lock(&(args->thr_mutex));
		args->pause_flag = 0;
		pthread_cond_signal(&(args->thr_cond));
		pthread_mutex_unlock(&(args->thr_mutex));
	}
#endif
}

void msp_thread_wait(msp_threadhandle thrd_hd)
{
#if defined(WIN32) || defined(WINCE)
#else
	p_thread_args args = (p_thread_args)thrd_hd;
	if ( args == 0 || args->thr_id == 0 )
		return;

	pthread_mutex_lock(&(args->thr_mutex));
	while ( args->pause_flag == 1 )
	{
		pthread_cond_wait(&(args->thr_cond), &(args->thr_mutex));
	}
	pthread_mutex_unlock(&(args->thr_mutex));
#endif
}
